package com.example.demo.controller;

import com.example.demo.controller.vo.ApplicationInfo;
import com.example.demo.domain.application.Application;
import com.example.demo.domain.application.ApplicationScale;
import com.example.demo.domain.application.CompanyApplication;
import com.example.demo.domain.application.PersonApplication;
import com.example.demo.domain.application.repository.ApplicationRepository;
import com.example.demo.domain.category.Category;
import com.example.demo.domain.category.repository.CategoryRepository;
import com.example.demo.domain.platform.Platform;
import com.example.demo.domain.platform.PlatformService;
import com.example.demo.domain.platform.PlatformRelease;
import com.example.demo.domain.user.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * 应用控制器
 *
 * @author yingjianhua
 */
@RestController
@RequestMapping(path = "application")
public class ApplicationController {

    @Autowired
    private LoginHolder loginHolder;
    @Autowired
    private PlatformService platformService;
    @Autowired
    private ApplicationRepository applicationRepository;
    @Autowired
    private CategoryRepository categoryRepository;
    @Autowired
    private ApplicationContext applicationContext;

    public void create(String name, String categoryName, String icon, String scale) throws Exception {
        final Category category = categoryRepository.findByName(categoryName).orElseThrow(() -> new RuntimeException("数据不存在"));
        Application application = applicationContext.getBean(ApplicationScale.ofCode(scale).getFactoryClass()).create(name, category, icon);
        applicationRepository.save(application);
    }

    public void changePaymentModel(String appCode, Byte paymentModel) throws Exception {
        final Application application = applicationRepository.findByCode(appCode).orElseThrow(() -> new RuntimeException("数据不存在"));
        application.setPaymentModel(paymentModel);
        applicationRepository.save(application);
    }

    public ApplicationInfo info(String appCode) throws Exception {
        final Application application = applicationRepository.findByCode(appCode).orElseThrow(() -> new RuntimeException("数据不存在"));
        return new ApplicationInfo(application, platformService.getReleaseInfo(application));
    }

    public void release(String appCode, String platformName, String releaseType, String releaseCode) throws Exception {
        final Application application = applicationRepository.findByCode(appCode).orElseThrow(() -> new RuntimeException("数据不存在"));
        platformService.release(application, Platform.valueOf(platformName), PlatformRelease.ReleaseType.valueOf(releaseType), releaseCode);
    }

    public void remove(String appCode, String platformName) throws Exception {
        final Application application = applicationRepository.findByCode(appCode).orElseThrow(() -> new RuntimeException("数据不存在"));
        platformService.remove(application, Platform.valueOf(platformName));
    }

    @RequestMapping(value = "person/open", method = RequestMethod.POST)
    public void open(String appCode) throws Exception {
        final Application application = applicationRepository.findByCode(appCode).orElseThrow(() -> new RuntimeException("数据不存在"));
        if (application instanceof PersonApplication) {
            PersonApplication personApplication = (PersonApplication) application;
            personApplication.open(loginHolder.getUser(), loginHolder.getUser());
        } else {
            throw new Exception("只有个人应用能开通");
        }
    }

    @RequestMapping(value = "person/close", method = RequestMethod.POST)
    public void close(String appCode) throws Exception {
        final Application application = applicationRepository.findByCode(appCode).orElseThrow(() -> new RuntimeException("数据不存在"));
        if (application instanceof PersonApplication) {
            PersonApplication personApplication = (PersonApplication) application;
            personApplication.close(loginHolder.getUser(), loginHolder.getUser());
        } else {
            throw new Exception("只有个人应用能关闭");
        }
    }

    @RequestMapping(value = "company/allopen", method = RequestMethod.POST)
    public void allOpen(String appCode) throws Exception {
        final Application application = applicationRepository.findByCode(appCode).orElseThrow(() -> new RuntimeException("数据不存在"));
        if (application instanceof CompanyApplication) {
            CompanyApplication companyApplication = (CompanyApplication) application;
            companyApplication.openCompanyScope(loginHolder.getUser());
        } else {
            throw new Exception("只有企业应用能开通");
        }
    }

    @RequestMapping(value = "company/open", method = RequestMethod.POST)
    public void batchOpen(String appCode, List<User> users) throws Exception {
        final Application application = applicationRepository.findByCode(appCode).orElseThrow(() -> new RuntimeException("数据不存在"));
        if (application instanceof CompanyApplication) {
            CompanyApplication companyApplication = (CompanyApplication) application;
            companyApplication.batchOpen(loginHolder.getUser(), users);
        } else {
            throw new Exception("只有企业应用能批量开通");
        }
    }
}
